<?php
declare (strict_types = 1);

namespace app\controller;

use app\model\User as UserModel;
use think\facade\Request as RequestFacade;
use think\helper\Str;
use think\Request;
use Exception;
use PHPMailer\PHPMailer\PHPMailer;
use think\exception\ValidateException;
use think\facade\Session;
use app\Model\User;
use think\facade\Db;
class Password
{

    public function showLinkRequestForm(){//填写 Email 的表单,第一步
            return view('password/show_link_request_form');
    }
    public function sendResetLinkEmail(Request $request){//处理表单提交，成功的话就发送邮件，附带 Token 的链接，第二步
        try {

            validate([
                'email|邮箱账号'=>'require|email|max:255|token',
            ])->batch()->check($request->post());
            $user= User::where('email',$request->post('email'))->findOrEmpty();
            if(!$user->isEmpty()){
                $obj=Db::table('password_reset')->where('email',$request->post('email'))->findOrEmpty();
                $email=$request->post('email');
                $token=sha1(Str::random(10).time());
                if(empty($obj)){
                    $data = [
                        'token'=>$token,
                        'email'=>$email,
                        'create_at'=>time()
                    ];
                    Db::name('password_reset')->save($data);
                }
                else{
                    $data = [
                        'id'=>$obj['id'],
                        'token'=>$token,
                        'email'=>$email,
                        'create_at'=>time()
                    ];
                    Db::name('password_reset')->save($data);
                }
                $this->sendEmailResetPasswordTo($token,$request->post('email'));
                return redirect((string) url('password.request'))->with('success','邮件发送成功，请查收~');
            }
            else{
                return redirect((string) url('password.request'))->with('danger','邮箱尚未注册');
            }


        } catch (ValidateException $e) {
            //记录旧的表单输入记录,闪存
            Session::flash('old',$request->post());
            if(!empty($errors=$e->getError()))
            {
                session('errors',$errors);//保存会话信息
                return redirect((string) url('password.request'));
            }


            // 验证失败
        }
    }

    public function showResetForm(Request $request){//显示更新密码的表单，包含 token，第四步
        $token=$request->param('token');
        $obj=Db::table('password_reset')->where('token',$token)->findOrEmpty();
        $email=$obj['email'];
        return view('password/show_reset_form',compact('token','email'));
    }

    public function reset(Request $request){//对提交过来的 token 和 email 数据进行配对，正确的话更新密码，第五步
        $token=$request->post('token');
        try {

            validate([
                 'token|令牌' => 'require' ,
                'password|密码'=>'require|min:6|confirm' ])->batch()->check($request->post());

            $email=$request->post('email');

           $user=User::where('email',$email)->findOrEmpty();
           $obj=Db::table('password_reset')->where('token',$token)->findOrEmpty();
           if($user->isEmpty()){
               return redirect((string) url('password.reset',['token'=>$token]))->with('danger','邮箱尚未注册~');
           }
            if(!empty($obj)){
                //判断token令牌是否失控
                if(time()>($obj['create_at']+config('app.token_expires'))){
                    return redirect((string) url('password.reset',['token'=>$token]))->with('danger','令牌失效');
                }
                if($token!=$obj['token']){
                    return redirect((string) url('password.reset',['token'=>$token]))->with('danger','令牌无效');
                }
                $user->password=sha1($request->post('password').getSalt());
                $user->save();
                return redirect((string) url('login.create'))->with('success','密码重置成功~');
            }

            return redirect((string) url('password.reset',['token'=>$token]))->with('danger','未找到相应记录~');

        } catch (ValidateException $e) {
            //记录旧的表单输入记录，闪存
            Session::flash('old',$request->post());
            if(!empty($errors=$e->getError()))
            {
                session('errors',$errors);//保存会话信息
                return redirect((string) url('password.reset',['token'=>$token]));
            }


            // 验证失败
        }

    }

    protected function sendEmailResetPasswordTo($token,$send_to_email){//第三步，发送找回密邮件
        $mail = new PHPMailer(true);
        try {
        // 服务器设置
            $mail->isSMTP();
            $mail->Host = config('email.host'); // SMTP 服务器
            $mail->SMTPAuth = true;
            $mail->Username = config('email.username'); // SMTP 用户名
            $mail->Password = config('email.password'); // SMTP 密码
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 启用 TLS加密
        $mail->Port = 587; // TCP 端口
        // 收件人
        $mail->setFrom(config('email.username'), 'Mailer');
        $mail->addAddress($send_to_email); // 添加收件人
        $url = RequestFacade::domain().url('password.reset',['token'=>$token]);
        // 邮件内容
        $mail->isHTML(true);
        $mail->Subject = '找回您的密码';
        $mail->Body = '请点击以下链接找回您的账户邮箱密码：<a href="'.$url.'">找回密码
        </a>';
        // 发送邮件
        $mail->send();
        } catch (Exception $e) {
                    return "邮件发送失败: {$mail->ErrorInfo}";
                }
    }



}
